import { defineStore } from 'pinia';
import { getToken, removeToken, setToken } from '../utils/token-utils';
import type { UserInfoState } from './interface';
import {allAsyncRoutes, staticRoutes,anyRoute} from '@/router/routes'
import { loginApi,logoutApi,getUserInfoApi } from '@/api/acl/login';
import type { RouteRecordRaw } from 'vue-router';
import router from '../router';
import cloneDeep from 'lodash/cloneDeep'

/**
 * 过滤得到用户拥有访问权限的路由表
 * @param allAsyncRoutes 所有异步路由菜单
 * @param routes 用户路由权限值
 */

const getPermissionRoutes = (allAsyncRoutes:RouteRecordRaw[],routes:string[])=>{
  return allAsyncRoutes.filter((route)=>{
    // 判断父级菜单是否包含权限值
    if(routes.includes(route.name as string)){
      // 如果有子菜单，子菜单也要进行过滤
      if(route.children && route.children.length > 0){
        route.children = getPermissionRoutes(route.children,routes)
      }
      return true
    }
    return false
  })
}

/**
 * 动态添加路由表
 * @param hasPermissionRoutes 用户拥有访问权限的路由表
 */
const addRoutes = (hasPermissionRoutes:RouteRecordRaw[])=>{
  hasPermissionRoutes.forEach((route)=>{
    // 动态添加路由
    router.addRoute(route)
  })
}


/**
 * 用户信息
 * @methods setUserInfos 设置用户信息
 */

export const useUserInfoStore = defineStore('userInfo', {

	state: (): UserInfoState => ({
    token: getToken() as string,
    name: '',
    avatar: '',
    routes:[],
    buttons:[],
    menuRoutes: []
  }),

	actions: {
    async login (username: string, password: string) {
      // 发送登录请求
      const {token} = await loginApi(username,password)
      // 登录成功将token存储起来
      // token将来就会在请求拦截器使用
      this.token = token // 存在pinia中（方便各个地方都可以使用）
      setToken(token)  // 存在localStorage中（持久化存储，下次刷新数据还在）
    },
    // 获取用户信息
    async getInfo () {
      const {name,avatar,buttons,routes} = await getUserInfoApi()
      // 用户名和头像在头部显示
      this.name = name
      this.avatar = avatar
      // 用来权限管理
      this.buttons = buttons
      this.routes = routes

      // 1. 根据用户路由权限值和所有异步路由表进行过滤，得到用户拥有访问权限的路由表hasPermissionRoutes
      // 根据用户的路由权限，来动态加载异步路由表
      const hasPermissionRoutes = getPermissionRoutes(cloneDeep(allAsyncRoutes),routes)
      // 2. 将用户拥有访问权限的路由表追加到路由配置中才能访问
      // 将异步路由表添加到路由配置项中才能访问
      addRoutes(hasPermissionRoutes)

       // 3. 将路由表更新到menuRoutes，将来左侧菜单就会根据menuRoutes的值来遍历生成左侧菜单
      // 左侧菜单要渲染的路由表
      // 只是渲染左侧菜单
      this.menuRoutes = [...staticRoutes,...hasPermissionRoutes,anyRoute]
    },

    // 退出登录
    async reset () {
      await logoutApi()
      // 删除local中保存的token
      removeToken()
      // 提交重置用户信息的mutation
      this.token = ''
      this.name = ''
      this.avatar = ''
    },
	},
});
